#include "restaurantdatamanager.h"
#include "datareceivedhandler.h"

#include <QJson/Serializer>
#include <QJson/Parser>

#include <QNetworkReply>
#include <QApplication>
#include <QUrl>

//#include <QDebug>

RestaurantDataManager::RestaurantDataManager(QObject *parent) :
    QObject(parent)
{
    connect(& m_NetworkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}

void RestaurantDataManager::searchLocationByAddress(const QString &apiKey, const QString &address)
{
   QString url = QString(
        "https://maps.googleapis.com/maps/api/geocode/json?"
        "address=%1&"
        "key=%2"
   ).arg(address, apiKey);

   sendRequest(url, new LocationHandler(this));
}

void RestaurantDataManager::searchRestaurantByLocation(const QString &apiKey, const QString &language, const QString &type, const QString &location)
{
    QString url = QString(
         "https://maps.googleapis.com/maps/api/place/nearbysearch/json?"
          "key=%1&"
          "location=%2&"
          "types=%3&"
          "radius=1000"
    ).arg(apiKey, location, type);

    if(!language.isEmpty()) url.append("&language=").append(language);

    sendRequest(url, new PlacesDataHandler(this));
}

void RestaurantDataManager::searchRestaurantDetails(const QString &apiKey, const QString &place_id, const QString &language)
{
    QString url = QString(
         "https://maps.googleapis.com/maps/api/place/details/json?"
          "key=%1&"
          "placeid=%2"
    ).arg(apiKey, place_id);

    if(!language.isEmpty()) url.append("&language=").append(language);

    sendRequest(url, new PlaceDetailsHandler(this));
}

void RestaurantDataManager::replyFinished(QNetworkReply *reply) const
{
    QApplication::restoreOverrideCursor();

    if( existsReplyError(reply) ) return;

    QString data = reply->readAll();

    QObject * origObject = reply->request().originatingObject();

    //qDebug() << data;

    DataReceivedHandler * handler = qobject_cast<DataReceivedHandler*>(origObject);
    if( ! handler ) {
        emit errorOccured(QString("data reiceved handler is null"));
        return;
    }

    //qDebug() << "Helper object present." ;
    handler->processData(data);
    handler->deleteLater();
}

void RestaurantDataManager::sendRequest(const QString &url, DataReceivedHandler *helper, RestaurantDataManager::RequestType type, const QByteArray &data)
{
    QNetworkRequest request;
    request.setOriginatingObject(helper);

//    qDebug() << Q_FUNC_INFO;
//    qDebug() << url;
//    qDebug() << "data" << data;

    request.setUrl( url );

    QApplication::setOverrideCursor(Qt::WaitCursor);

    if( type == Post || type == Put )
    {
        request.setRawHeader("Content-Type", "application/json");
    }

    switch(type)
    {
        case Get:       m_NetworkAccessManager.get( request ); break;
        case Post:      m_NetworkAccessManager.post( request, data ); break;
        case Put:       m_NetworkAccessManager.put( request, data ); break;
        case Delete:    m_NetworkAccessManager.deleteResource( request ); break;
    }
}

bool RestaurantDataManager::existsReplyError(const QNetworkReply *reply) const
{
    // Client Error 4xx
    // Server Error 5xx

    if( 399 < reply->error() )
    {
        emit errorOccured( reply->errorString() );
        return true;
    }

    return false;
}
